#include "BrokerServer.h"
#include "BrokerServantImp.h"
#include "log.h"

using namespace std;

BrokerServer g_app;
const uint32_t PKG_MIN_SIZE = 4;
const uint32_t PKG_MAX_SIZE = 640000;

/////////////////////////////////////////////////////////////////

struct GamoosProtocol
{
    static TC_NetWorkBuffer::PACKET_TYPE parse(TC_NetWorkBuffer &in, vector<char> &out)
    {
        if (in.getBufferLength() < PKG_MIN_SIZE)
        {
            return TC_NetWorkBuffer::PACKET_LESS;
        }
        
        string header;
        in.getHeader(PKG_MIN_SIZE, header);
        
        assert(header.size() == PKG_MIN_SIZE);
        
        uint32_t packLen = 0;
        
        ::memcpy(&packLen, header.c_str(), PKG_MIN_SIZE);
        
        packLen = ntohl(packLen);
        
        DEBUG("packLen:"<<packLen);
        
        if (packLen > PKG_MAX_SIZE || packLen < PKG_MIN_SIZE)
        {
            throw TarsDecodeException("packet length too long or too short,len:" + TC_Common::tostr(packLen));
        }
        
        if (in.getBufferLength() < (uint32_t)packLen)
        {
            return TC_NetWorkBuffer::PACKET_LESS;
        }
        
        in.moveHeader(PKG_MIN_SIZE);
        
        in.getHeader(packLen, out);
        in.moveHeader(packLen);
        
        return TC_NetWorkBuffer::PACKET_FULL;
    }
};

void
BrokerServer::initialize()
{
    //initialize application here:
    
    addServant<BrokerServantImp>(ServerConfig::Application + "." + ServerConfig::ServerName + ".BrokerServantObj");
    
    //    设置监听端口的协议解析器,非WS格式
    addServantProtocol(ServerConfig::Application + "." + ServerConfig::ServerName + ".BrokerServantObj", &GamoosProtocol::parse);
    
}
/////////////////////////////////////////////////////////////////
void
BrokerServer::destroyApp()
{
    //destroy application here:
    //...
}

void BrokerServer::sendDataToClient(tars::TarsCurrentPtr current, const gamoosim::ABCPack &req)
{
    if (current == nullptr)
    {
        ERROR("current is null!");
        return;
    }
    
    std::vector<char> data;
    packTars<gamoosim::ABCPack>(req, data);
    DEBUG("pack type:"<<pack.writeToJsonString());
    current->sendResponse(data.data(), data.size());
}

/////////////////////////////////////////////////////////////////
int
main(int argc, char* argv[])
{
    try
    {
        g_app.main(argc, argv);
        g_app.waitForShutdown();
    }
    catch (std::exception& e)
    {
        cerr << "std::exception:" << e.what() << std::endl;
    }
    catch (...)
    {
        cerr << "unknown exception." << std::endl;
    }
    return -1;
}
/////////////////////////////////////////////////////////////////
